package mns.modules.input.weatherbug;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import com.abso.weatherbug.core.*;
import com.abso.weatherbug.core.data.*;

import mns.*;

/**
 * A WeatherBug API Module, using XML
 * 
 * WeatherBug API Documentation:
 * http://weather.weatherbug.com/corporate/products/API/help.aspx#forecast
 * 
 * Uses HTTP calls to get XML via a zipcode -> location -> info path.
 * 
 * Can be configured for day of week 7 day forecast or instant alerts
 * 
 * @author Dan Moore
 *
 */
public class WeatherForecastModule implements MNSInputModule {

	private static final String API_KEY = "A5465474673";
	
	public String getName() {
		return "WeatherBug Forecast Module";
	}

	public String getOptionsFormHTML() {
		String html = "Zip Code: <input type=\"text\" name=\"zipcode\" value=\"30332\" />";
		return html;
	}

	public String getDescriptionHTML() {
		// TODO Auto-generated method stub
		return "";
	}
	
	public static Document parseFile(File xml) {
		DocumentBuilder docBuilder;
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(true);
		try {
			docBuilder = dbf.newDocumentBuilder();
			doc = docBuilder.parse(xml);
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return doc;
	}
	
	private static String getShortMsg(WeatherBugService wbs, int zip) {
		Forecasts fc;
		try {
			fc = wbs.getForecastByUSZipCode(zip, 0);
		} catch (WeatherBugServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
		String msg = "For "+fc.getCity()+","+fc.getState()+": ";
		Forecast[] fcs = fc.getForecasts();
		
		for(int i = 0; i < 3; i++) {
			msg+= shortenTitle(fcs[i].getTitle())+": ";
			msg+= ""+fcs[i].getLowestTemperature()+"-"+fcs[i].getHighestTemperature()+"\u00B0F, "+fcs[i].getShortPrediction()+". ";
		}
		
		return msg;
	}
	
	private static String getLongMsg(WeatherBugService wbs, int zip) {
		Forecasts fc;
		try {
			fc = wbs.getForecastByUSZipCode(zip, 0);
		} catch (WeatherBugServiceException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
		
		String msg = "Here is your 7 day forecast for "+fc.getCity()+", "+fc.getState()+" ("+zip+"): \n";
		Forecast[] fcs = fc.getForecasts();
		
		for(int i = 0; i < fcs.length; i++) {
			msg+=fcs[i].getTitle()+": \n";
			msg+="\tHigh of "+fcs[i].getHighestTemperature()+"\u00B0F,";
			msg+=" low of "+fcs[i].getLowestTemperature()+"\u00B0F.\n";
			msg+="\t"+fcs[i].getPrediction()+". \n";
		}
		
		return msg;
	}
	
	/**
	 * Queries weatherbug forecase web API
	 * Example file: http://A5465474673.api.wxbug.net/getForecastRSS.aspx?ACode=A5465474673&zipCode=30332&UnitType=0&OutputType=1
	 * @param zipcode
	 * @return
	 */
	public static MNSMessage getForecastByZip(int zip) {
		WeatherBugService wbs = new WeatherBugService(API_KEY);
		MNSMessage msg = new MNSMessage(getLongMsg(wbs, zip),getShortMsg(wbs, zip));
		return msg;
	}
	
	public MNSMessage getMessage(UserOptions opts) {
		UserOption opt;
		int zipcode;
		
		try {
			opt = opts.getOption("zipcode");
			zipcode = Integer.parseInt(opt.getValue());
		} catch(NullPointerException e) {
			System.err.println("Bad User Options, not getting msg from WeatherForecastModule.");
			return null;
		}
		
		return getForecastByZip(zipcode);

	}

	public NotificationType getType() {
		return NotificationType.SCHEDULED;
	}

	public static String shortenTitle(String title) {
		if(title.equals("Monday")) {
			return "M";
		} else if(title.equals("Tuesday")) {
			return "T";
		} else if(title.equals("Wednesday")) {
			return "W";
		} else if(title.equals("Thursday")) {
			return "R";
		} else if(title.equals("Friday")) {
			return "F";
		} else if(title.equals("Saturday")) {
			return "Sa";
		} else if(title.equals("Sunday")) {
			return "Su";
		} else {
			return "?";
		}
	}
	
	/*
	public static void main(String[] args) throws URISyntaxException, WeatherBugServiceException {
		MNSMessage msg = getForecastByZip(30332);
		System.out.println("Short MSG:\n"+msg.getShortMessage());
		System.out.println("Long MSG:\n"+msg.getLongMessage());
	}*/
	
}
